﻿using SQLiteSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using YunLuPos.Entity;
using YunLuPos.Entity.Constant;

namespace YunLuPos.DB.Service
{
    public class SaleOrderService
    {
        private log4net.ILog logger = log4net.LogManager.GetLogger(typeof(SaleOrderService));
        private CodesService codesService = new CodesService();
        /**
         * 根据基础信息创建售卖单据
         * cominfo 基础信息
         * isReject 是否退单
         * */
        public SaleOrder createNewOrder(CommInfo commInfo,Boolean isReject = false)
        {
            String orderCode = null;
            while (true)
            {
                orderCode = codesService.genNowOrderCode(commInfo.shopCode,commInfo.posCode);
                if(orderCode != null)
                {
                    break;
                }
            }
            DBLocker.setLocker();
            try
            {
                using (SqlSugarClient db = SugarDao.GetInstance())
                {
                    SaleOrder newOrder = new SaleOrder();
                    newOrder.orderCode = orderCode;
                    newOrder.orderId = Guid.NewGuid().ToString("N");
                    newOrder.orderType = isReject ? SaleOrderType.REJECT.ToString() : SaleOrderType.SALE.ToString();
                    newOrder.cliqueCode = commInfo.cliqueCode;
                    newOrder.branchCode = commInfo.shopCode;
                    newOrder.posCode = commInfo.posCode;
                    newOrder.cashierCode = commInfo.cashierCode;
                    newOrder.cashierName = commInfo.cashierName;
                    newOrder.saleDate = DateTime.Now.ToString("yyyy-MM-dd");
                    newOrder.createTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    newOrder.realAmount = 0;
                    newOrder.payAmount = 0;
                    newOrder.disAmount = 0;
                    newOrder.dotAmount = 0;
                    newOrder.state = SaleOrderState.NEW.ToString();
                    Int64 result = (Int64)db.Insert<SaleOrder>(newOrder);
                    if(result > 0)
                    {
                        return newOrder;
                    }
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
            finally
            {
                DBLocker.release();
            }
            return null;
        }

        /**
         * 获取完整订单
         * */
        public SaleOrder getFullOrder(String orderNo)
        {
            DBLocker.setLocker();
            try
            {
                using (SqlSugarClient db = SugarDao.GetInstance())
                {
                    SaleOrder order =  db.Queryable<SaleOrder>().Where(it => it.orderCode == orderNo).SingleOrDefault();
                    if(order == null)
                    {
                        return null;
                    }
                    List<SaleOrderGoods> goods = db.Queryable<SaleOrderGoods>().Where(it => it.orderCode == orderNo).ToList();
                    List<SaleOrderAccount> accounts = db.Queryable<SaleOrderAccount>().Where(it => it.orderCode == orderNo).ToList();
                    order.goods = goods;
                    order.accounts = accounts;
                    return order;
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
            finally
            {
                DBLocker.release();
            }
            return null;
        }


        /**
        * 作废单据
        * */
        public Boolean makeDirty(SaleOrder order)
        {
            if(order == null || order.orderId == null)
            {
                return false;
            }
            DBLocker.setLocker();
            try
            {
                using (SqlSugarClient db = SugarDao.GetInstance())
                {
                    return db.Update<SaleOrder>(new {
                        state = SaleOrderState.DIRTY.ToString(),
                        doneTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                   },it => it.orderId == order.orderId);
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
            finally
            {
                DBLocker.release();
            }
            return false;
        }

        /**
        * 获取单据支付状态
        * isLessCent 默认不处理舍分
        * */
        public PaymentState getPaymentState(String orderCode,String isLessCent)
        {
            if (orderCode == null)
            {
                return null;
            }
            DBLocker.setLocker();
            try
            {
                using (SqlSugarClient db = SugarDao.GetInstance())
                {
                    SaleOrder order = db.Queryable<SaleOrder>().Where(it => it.orderCode == orderCode).SingleOrDefault();
                    if(order != null)
                    {
                        PaymentState state = new PaymentState();
                        state.needPay = order.payAmount;
                        state.dot = order.dotAmount;
                        List<SaleOrderAccount> accounts = db.Queryable<SaleOrderAccount>().Where(it => it.orderCode == orderCode).ToList();
                        if(accounts == null || accounts.Count <= 0)
                        {
                            state.payed = 0;
                            state.change = 0;
                            state.less = state.needPay;
                        }else
                        {
                            Double payed = 0.00;
                            accounts.ForEach(l => {
                                if ("CHANGE".Equals(l.typeKey))
                                {
                                    state.change = l.amount;
                                }
                                payed = payed + l.amount;
                            });
                            state.payed = payed;
                            state.less = Math.Round(state.needPay - payed, 2);
                        }
                        //处理舍分（不同支付方式舍分）
                        if ("1".Equals(isLessCent))
                        {
                            logger.Debug("计算舍分");
                            logger.Debug("应付:"+state.needPay);
                            Double oldNeedPay = state.needPay;
                            String needStr = state.needPay.ToString();
                            if (needStr.IndexOf(".") > 0)
                            {
                                needStr = needStr.Substring(0, needStr.IndexOf(".") + 2);
                            }
                            logger.Debug("截取字符串:" + needStr);
                            state.needPay = Double.Parse(needStr);
                            logger.Debug("解析应付:" + state.needPay);
                            state.less = Math.Round(state.needPay - state.payed, 2);
                            state.dot = Math.Round(oldNeedPay - state.needPay,2);
                            logger.Debug("舍分金额:" + state.dot);
                        }
                        return state;
                    }
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
            finally
            {
                DBLocker.release();
            }
            return null;
        }

        /**
        * 单据支付完成
        * */
        public Boolean done(SaleOrder order,PaymentState state)
        {
            if (order == null || order.orderId == null)
            {
                return false;
            }
            if(state.less != 0)
            {
                return false;
            }
            DBLocker.setLocker();
            try
            {
                using (SqlSugarClient db = SugarDao.GetInstance())
                {
                    return db.Update<SaleOrder>(new
                    {
                        dotAmount = state.dot,
                        state = SaleOrderState.PAYED.ToString(),
                        saleDate = DateTime.Now.ToString("yyyy-MM-dd"),
                        doneTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                    }, it => it.orderId == order.orderId);
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
            finally
            {
                DBLocker.release();
            }
            return false;
        }


        /**
        * 挂单
        * */
        public Boolean hoderOrder(SaleOrder order,Boolean isHold)
        {
            if (order == null || order.orderId == null)
            {
                return false;
            }
            DBLocker.setLocker();
            try
            {
                using (SqlSugarClient db = SugarDao.GetInstance())
                {
                    if (isHold)
                    {
                        return db.Update<SaleOrder>(new
                        {
                            state = SaleOrderState.HOLD.ToString()
                        }, it => it.orderId == order.orderId && it.state == SaleOrderState.NEW.ToString());
                    }else
                    {
                        return db.Update<SaleOrder>(new
                        {
                            state = SaleOrderState.NEW.ToString()
                        }, it => it.orderId == order.orderId && it.state == SaleOrderState.HOLD.ToString());
                    }
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
            finally
            {
                DBLocker.release();
            }
            return false;
        }


        /**
        * 设置会员
        * */
        public Boolean setMemberInfo(SaleOrder order, Member member)
        {
            if (order == null)
            {
                return false;
            }
            DBLocker.setLocker();
            try
            {
                using (SqlSugarClient db = SugarDao.GetInstance())
                {
                    if(member == null || member.mebCode == null || member.mebName == null)
                    {
                        return db.Update<SaleOrder>(new
                        {
                            memberNo = "",
                            memberName = ""
                        }, it => it.orderId == order.orderId && it.state == SaleOrderState.NEW.ToString());
                    }
                    else
                    {
                        return db.Update<SaleOrder>(new
                        {
                            memberNo = member.mebCode,
                            memberName = member.mebName
                        }, it => it.orderId == order.orderId && it.state == SaleOrderState.NEW.ToString());
                    }
                    
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
            finally
            {
                DBLocker.release();
            }
            return false;
        }

        /**
         * 获取挂单列表
         * */
        public List<SaleOrder> listHoderOrder()
        {
            DBLocker.setLocker();
            try
            {
                using (SqlSugarClient db = SugarDao.GetInstance())
                {
                    return db.Queryable<SaleOrder>().Where(it => it.state == SaleOrderState.HOLD.ToString()).ToList();
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
            finally
            {
                DBLocker.release();
            }
            return null;
        }

        /**
         * 获取未上传列表
         * */
        public List<SaleOrder> listUnSyncOrder()
        {
            DBLocker.setLocker();
            try
            {
                using (SqlSugarClient db = SugarDao.GetInstance())
                {
                    return db.Queryable<SaleOrder>().Where(it => it.state == SaleOrderState.PAYED.ToString()).ToList();
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
            finally
            {
                DBLocker.release();
            }
            return null;
        }


        /**
         * 获取交易列表
         * */
        public List<SaleOrder> listDayOrder(String date,String cashierCode)
        {
            DBLocker.setLocker();
            try
            {
                using (SqlSugarClient db = SugarDao.GetInstance())
                {
                    if(cashierCode == null)
                    {
                     return db.Queryable<SaleOrder>().Where(it =>

                            it.saleDate == date &&

                            (it.state == SaleOrderState.PAYED.ToString() || it.state == SaleOrderState.SYNCED.ToString())
                            
                        ).OrderBy(it => it.id , OrderByType.Desc )
                        .ToList();

                    }else
                    {
                        return db.Queryable<SaleOrder>().Where(it =>

                           it.saleDate == date &&
                           it.cashierCode == cashierCode &&
                           (it.state == SaleOrderState.PAYED.ToString() || it.state == SaleOrderState.SYNCED.ToString())

                       ).OrderBy(it => it.id, OrderByType.Desc)
                       .ToList();
                    }
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
            finally
            {
                DBLocker.release();
            }
            return null;
        }


        /**
       * 单据支付完成
       * */
        public Boolean synced(SaleOrder order)
        {
            if (order == null || order.orderId == null)
            {
                return false;
            }
            DBLocker.setLocker();
            try
            {
                using (SqlSugarClient db = SugarDao.GetInstance())
                {
                    return db.Update<SaleOrder>(new
                    {
                        state = SaleOrderState.SYNCED.ToString()
                    }, it => it.orderId == order.orderId && it.state == SaleOrderState.PAYED.ToString());
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
            finally
            {
                DBLocker.release();
            }
            return false;
        }

        /**
       * 切换单据销售、退货模式
       * */
        public Boolean changeOrderType(SaleOrder order)
        {
            if (order == null || order.orderId == null)
            {
                return false;
            }
            DBLocker.setLocker();
            try
            {
                using (SqlSugarClient db = SugarDao.GetInstance())
                {
                    if (SaleOrderType.SALE.ToString().Equals(order.orderType))
                    {
                        //销售
                        return db.Update<SaleOrder>(new
                        {
                            orderType = SaleOrderType.REJECT.ToString()
                        }, it => it.orderId == order.orderId && it.orderType == SaleOrderType.SALE.ToString());
                    }else if (SaleOrderType.REJECT.ToString().Equals(order.orderType))
                    {
                        return db.Update<SaleOrder>(new
                        {
                            orderType = SaleOrderType.SALE.ToString()
                        }, it => it.orderId == order.orderId && it.orderType == SaleOrderType.REJECT.ToString());
                    }
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
            finally
            {
                DBLocker.release();
            }
            return false;
        }

        
        /// <summary>
        /// 清除所有单据
        /// </summary>
        public void cleanAll()
        {
            
            String dayPre7 = DateTime.Now.AddDays(-3).ToString("yyyy-MM-dd");
            DBLocker.setLocker();
            try
            {
                using (SqlSugarClient db = SugarDao.GetInstance())
                {
                    db.Delete<SaleOrder>("where state = 'SYNCED' AND saleDate < '"+dayPre7+"'");
                    db.Delete<SaleOrderGoods>("WHERE orderCode NOT IN (SELECT orderCode FROM SaleOrder)");
                    db.Delete<SaleOrderGoods>("WHERE orderCode NOT IN (SELECT orderCode FROM SaleOrder)");
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
            finally
            {
                DBLocker.release();
            }
        }

        /// <summary>
        /// 根据单据id生成打印字符串列表，以行为单位
        /// </summary>
        /// <param name="orderId"></param>
        /// <returns></returns>
        public List<String> PrintList(String orderCode)
        {
            if (String.IsNullOrEmpty(orderCode)) return null;
            SaleOrder order = getFullOrder(orderCode);
            List<String> listStr = new List<string>();
            //判断是否存在银联支付
            StringBuilder sb = new StringBuilder();
            listStr.Add("===============================");
            sb.Clear();
            sb.Append("类型:");
            if (SaleOrderType.SALE.ToString().Equals(order.orderType))
            {
                sb.Append("销售");
            }
            else if (SaleOrderType.REJECT.ToString().Equals(order.orderType))
            {
                sb.Append("退货");
            }
            listStr.Add(sb.ToString());

            sb.Clear();
            sb.Append("票号:");
            sb.Append(order.orderCode);
            listStr.Add(sb.ToString());

            sb.Clear();
            sb.Append("店号:");
            sb.Append(order.branchCode + " ");
            sb.Append(order.doneTime);
            listStr.Add(sb.ToString());

            sb.Clear();
            sb.Append("收银员:");
            sb.Append(order.cashierCode +" "+ order.cashierName);
            listStr.Add(sb.ToString());

            sb.Clear();
            sb.Append("收银机号:");
            sb.Append(order.posCode);
            listStr.Add(sb.ToString());

            

            if (!String.IsNullOrEmpty(order.memberName))
            {
                sb.Clear();
                sb.Append("会员:");
                sb.Append(order.memberNo);
                listStr.Add(sb.ToString());
            }

            //合计促销商品总价与非促销商品总价
            Double normAmount = 0;
            Double promAmount = 0;

            listStr.Add("名称         数量   单价   小计");
            listStr.Add("===============================");
            if (order.goods != null)
                foreach (SaleOrderGoods sog in order.goods)
                {
                    if (GoodsPriceSource.NORM.ToString().Equals(sog.priceSource))
                    {
                        listStr.Add((order.goods.IndexOf(sog) + 1) + "." + sog.goodsName);
                        normAmount = normAmount + sog.payAmount;
                    }else
                    {
                        //listStr.Add((order.goods.IndexOf(sog) + 1) + ".[" + sog.priceSource.Substring(0, 1) + "]" + sog.goodsName);
                        listStr.Add((order.goods.IndexOf(sog) + 1) + ".【促】" + sog.goodsName);
                        promAmount = promAmount + sog.payAmount;

                    }
                    sb.Clear();
                    String barcode = "";
                    if (sog.barCode.Length > 13)
                    {
                        barcode = sog.barCode.Substring(0, 7);
                    }
                    else
                    {
                        barcode = sog.barCode.ToString();
                    }
                    sb.Append(barcode.PadRight(14, ' '));
                    sb.Append(sog.goodsCount.ToString().PadRight(5, ' '));
                    sb.Append(" ");

                    sb.Append(String.Format("{0:F2}", sog.disPrice).PadRight(5, ' '));

                    sb.Append(" ");
                    sb.Append(String.Format("{0:F2}", sog.payAmount).PadRight(5, ' '));
                    listStr.Add(sb.ToString());
                }
            listStr.Add("-------------------------------");
            //优惠合计
            sb.Clear();
            sb.Append("正价商品合计：");
            sb.Append(String.Format("{0:F2}", normAmount));
            listStr.Add(sb.ToString());

            sb.Clear();
            sb.Append("促销商品合计：");
            sb.Append(String.Format("{0:F2}", promAmount));
            listStr.Add(sb.ToString());

            sb.Clear();
            listStr.Add("-------------------------------");
            sb.Clear();
            if (SaleOrderType.SALE.ToString().Equals(order.orderType))
            {
                sb.Append("应收: ");
            }
            else if (SaleOrderType.REJECT.ToString().Equals(order.orderType))
            {
                sb.Append("应退：");
            }

            

            String disAmountDisplay = String.Format("{0:F2}", order.disAmount);
            String amountDisplay = String.Format("{0:F2}", order.payAmount);
            String needDisplay = String.Format("{0:F2}", order.realAmount);

            sb.Append(needDisplay.PadRight(10, ' '));
            sb.Append("件数: ");
            sb.Append(order.goodsCount);
            listStr.Add(sb.ToString());

            sb.Clear();
            if (SaleOrderType.SALE.ToString().Equals(order.orderType))
            {
                sb.Append("实收: ");
            }
            else if (SaleOrderType.REJECT.ToString().Equals(order.orderType))
            {
                sb.Append("实退：");
            }
            sb.Append(amountDisplay.PadRight(10, ' '));
            sb.Append("共优惠: ");
            sb.Append(disAmountDisplay);
            listStr.Add(sb.ToString());
            listStr.Add("-------------------------------");

            if (order.accounts != null)
            {
                foreach (SaleOrderAccount dr in order.accounts)
                {
                    sb.Clear();
                    sb.Append(dr.typeName);
                    sb.Append(": ");
                    sb.Append(String.Format("{0:F2}", dr.amount));
                    listStr.Add(sb.ToString());
                    sb.Clear();
                    Console.WriteLine("MEMBER".Equals(dr.typeKey));
                    if ("MEMBER".Equals(dr.typeKey))
                    {
                        String name = "";
                        String phone = "";
                        String lessAmt = "";
                        String menbPayStr = dr.trandNo;
                        if(menbPayStr != null)
                        {
                            try
                            {
                                String[] infos = menbPayStr.Split(',');
                                name = infos[0];
                                phone = infos[1];
                                lessAmt = infos[2];
                            }
                            catch(Exception e)
                            {
                                logger.Error(e);
                            }
                        }
                        listStr.Add("会员姓名: " + name);
                        listStr.Add("手 机 号: " + phone);
                        listStr.Add("余    额: " + lessAmt);
                    }
                    else
                    {
                        if (dr.trandNo != null)
                        {
                            String name = "";
                            String phone = "";
                            String lessAmt = "";
                            String menbPayStr = dr.trandNo;
                            if (menbPayStr != null)
                            {
                                try
                                {
                                    String[] infos = menbPayStr.Split(',');
                                    name = infos[0];
                                    phone = infos[1];
                                    lessAmt = infos[2];
                                }
                                catch (Exception e)
                                {
                                    logger.Error(e);
                                }
                            }
                            listStr.Add("会员姓名: " + name);
                            listStr.Add("手 机 号: " + phone);
                            listStr.Add("余    额: " + lessAmt);
                            //listStr.Add("交易号: " + dr.trandNo);
                        }

                        
                    }
                    
                }
            }
            if(order.memberNo != null && order.memberName != null)
            {
                listStr.Add("-------------------------------");
                listStr.Add("会员姓名:"+order.memberName);
                listStr.Add("会员编号:" + order.memberNo);
            }
            listStr.Add("===============================");
            listStr.Add("     ");
            return listStr;
        }

    }
}
